import Request from '@/common/request/luch-request/index.js'
import Encrypt from '@/common/utils/crypto.js'
import store from '@/common/store';
import { baseUrl } from '@/config/devServer';
import lodash from 'lodash'

class MinRequest {
  constructor() {
    this.queue = {};
    this.httpList = []; // 请求中的接口列表
    this.loadingTimeOut = null; // 关闭loading延时器
    this.outLoginTimer = null; // 退出登录延迟
    // 初始化方法
    this.http = new Request(); // 请求方法
    // 加密参数
    this.encrypt = new Encrypt(); // 加密方法
    this.key = '';
  }
  initFn () {
    this.interceptors();
    // #ifdef MP-WEIXIN | APP-PLUS
    this.http.config.baseURL = baseUrl;
    // #endif
    return this.http;
  };
  interceptors () {
    this.http.interceptors.request.use((config) => { // 可使用async await 做异步操作
      const {
        isToken, // 是否拼接ImpToken
        isLoading, // 是否打开loading
        isEncrypt // 是否加密
      } = config.custom;
      const token = store.getters.token;
      config.header = {
        ...config.header
      }
      config.header.Accept = '*/*';
      // 请求头，拼接token
      if (isToken !== false) {
        config['x-cloudbase-credentials'] = token;
        // config.header._ImpToken_ = token;
      }
      // 加密上传参数
      // let params = config.data;
      // if (params && isEncrypt !== false) {
      //   config.data = this.cloneParams(params);
      // }
      // 判断是否弹出loading
      if (isLoading !== false) {
        this.httpList.push(config.url);
      }
      // 判断是否需要打开loading
      if (this.httpList.length) {
        uni.showLoading({
          title: '加载中...',
          mask: true
        });
      }
      this.queue[config.url] = true;
      return config;
    }, (config) => { // 可使用async await 做异步操作
      return Promise.reject(config)
    })

    this.http.interceptors.response.use((response) => { /* 对响应成功做点什么 可使用async await 做异步操作*/
      const { isRequestTip } = response.config.custom;
      // 拦截响应，弹出对应信息
      const jsonData = response.data;
      if (
        jsonData &&
        jsonData.code &&
        jsonData.code !== 200 &&
        jsonData.code !== 430 &&
        isRequestTip !== false
      ) {
        uni.showToast({
          title: jsonData.message,
          icon: 'none', //不要图标
          position: 'top',
          duration: 2000 // 2秒后消失
        })
        if (
          Number(jsonData.code) === 508 || // 508 TOKEN无效
          Number(jsonData.code) === 401 || // 401 访问未授权 跳转到登录页面
          Number(jsonData.code) === 510 || // 510 授权过期 跳转到登录页面
          Number(jsonData.code) === 607
        ) {
          if (this.outLoginTimer) {
            clearTimeout(this.outLoginTimer);
          }
          this.outLoginTimer = setTimeout(() => {
            uni.redirectTo({
              url: '/pages/login/login?noAutoLogin=1'
            });
          }, 3000);
        }
      }
      this.destroy(response.config);
      return jsonData
    }, (response) => { /*  对响应错误做点什么 （statusCode !== 200）*/
      // this.destroy(response.config);
      return Promise.reject(response)
    })
  };
  // 删除请求列表中的请求 并停止loading
  destroy (params) {
    const url = params.url;
    const i = this.httpList.indexOf(url);
    if (i >= 0 && params.custom.isLoading !== false) {
      this.httpList.splice(i, 1);
    }
    if (!this.httpList.length) {
      if (this.loadingTimeOut) {
        clearTimeout(this.loadingTimeOut);
        this.loadingTimeOut = null;
      }
      this.loadingTimeOut = setTimeout(() => {
        uni.hideLoading();
      }, 200)
    }
  };
  // 上行参数 clone
  cloneParams (params) {
    const tempParams = lodash.cloneDeep(params);
    return this.isArrayOrMap(tempParams);
  }
  // 判断数据对象是MAP还是ARRAY
  isArrayOrMap (data) {
    if (Object.prototype.toString.call(data) === '[object Array]') {
      return this.dataArray(data)
    } else if (Object.prototype.toString.call(data) === '[object Object]') {
      return this.dataMap(data)
    }
  }
  // Object类型分解加密
  dataMap (dataMap) {
    for (const item in dataMap) {
      if (!this.isArrayOrMap(dataMap[item])) {
        dataMap[item] = dataMap[item] === null || dataMap[item] === undefined ? '' : dataMap[item];
        // dataMap[item] = this.encrypt.encrypt(dataMap[item], this.key); // 对称加密
        dataMap[item] = this.encrypt.keyJsencrypt(dataMap[item]); // 非堆成加密
      }
    }
    return dataMap;
  };
  // Array类型分解加密
  dataArray (dataArray) {
    for (let i = 0; i < dataArray.length; i++) {
      if (!this.isArrayOrMap(dataArray[i])) {
        dataArray[i] = dataArray[i] === null || dataArray[i] === undefined ? '' : dataArray[i];
        // dataArray[i] = this.encrypt.encrypt(dataArray[i], this.key) // 对称加密
        dataMap[item] = this.encrypt.keyJsencrypt(dataMap[item]); // 非堆成加密
      }
    }
    return dataArray;
  };
}

export default (new MinRequest()).initFn();
